home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Twin
/
EvalDelegate.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
8KB
|
283 lines
/* Generated by Interface Builder */
static char copyright[] = "Copyright 1990 by The MITRE Corporation.";
/* John D. Ramsdell - June 1990
*
* Copyright 1990 by The MITRE Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* MAXHISTORYTEXT gives the maximum amount of text allowed in the history
* text window. When the limit is exceeded, the first MAXHISTORYTEXT/2
* characters are deleted.
*/
#if !defined MAXHISTORYTEXT
#define MAXHISTORYTEXT (1 << 18)
#endif
#import "EvalDelegate.h"
#import "EvalListener.h"
#import "startSlaveProcess.h"
#import <appkit/Application.h>
#import <appkit/Font.h>
#import <defaults/defaults.h>
#import <appkit/appkit.h>
#import <appkit/ScrollView.h>
#import <appkit/Text.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
static NXCharFilterFunc defaultEditorFilter;
/* This makes the inputText view end input when ENTER is typed. */
#define NX_ENTER 3
static unsigned short
inputEditorFilter(unsigned short theChar, int flags, unsigned short charSet)
{
if (flags & NX_COMMANDMASK) return 0;
if (theChar == NX_ENTER) return NX_RETURN;
return (*defaultEditorFilter) (theChar, flags, charSet);
}
FILE *processOut; /* Place to write to the slave process. */
@implementation EvalDelegate
void startEvalListener(EvalDelegate *evalDelegate)
{
EvalListener *evalListener; /* Start listener for remote messages. */
evalListener = [EvalListener new];
[evalListener setDelegate:evalDelegate];
[evalListener checkInAs:"Twin"];
[evalListener addPort];
}
Font *getFont(void)
{
const char *fontname;
float fontsize;
static NXDefaultsVector twinDefaults = {
{"SlaveCommand", "t"},
{"Columns", "80"},
{"NXFixedPitchFont", "Ohlfs"},
{"NXFixedPitchFontSize", "10.0" },
{NULL}
};
NXRegisterDefaults("Twin", twinDefaults);
fontname = NXGetDefaultValue("Twin", "NXFixedPitchFont");
fontsize = atof(NXGetDefaultValue("Twin", "NXFixedPitchFontSize"));
return [Font newFont:fontname size:fontsize];
}
- setHistoryScrollView:anObject
{
NXCoord widthInChars;
NXRect historyRect, windowRect;
id window;
NXCoord width;
historyScrollView = anObject;
historyText = [historyScrollView docView];
displayFont = getFont();
/* Set width of windows. */
widthInChars = atoi(NXGetDefaultValue("Twin", "Columns"));
if (widthInChars < 20.0) widthInChars = 20.0;
width = widthInChars
* ([displayFont getWidthOf:" "] - [displayFont getWidthOf:" "]);
[historyText getFrame:&historyRect];
window = [historyText window];
[window getFrame:&windowRect];
width += NX_WIDTH(&windowRect) - NX_WIDTH(&historyRect);
[window sizeWindow:width :NX_HEIGHT(&windowRect)];
[historyText setFont:displayFont];
startEvalListener(self);
return self;
}
- setInputScrollView:anObject
{
inputScrollView = anObject;
inputText = [inputScrollView docView];
defaultEditorFilter = [inputText charFilter];
[inputText setCharFilter:inputEditorFilter];
[inputText setDelegate:self];
return self; /* Font set in appDidInit. */
}
static BOOL stringVisibleMode = TRUE;
- toggleStringVisibleMode:sender
{
stringVisibleMode = !stringVisibleMode;
return self;
}
void selectEnd(id text)
{
int length;
length = [text textLength];
[text setSel:length :length];
}
- showString:(char *)string /* Add text to history view. */
{
int length;
length = [historyText textLength];
if (length >= MAXHISTORYTEXT) {
[historyText setSel:0 :(MAXHISTORYTEXT>>1)-1];
[historyText setEditable:YES];
[historyText delete:self]; /* Delete first half of text. */
return [self showString:string]; /* Try again. */
}
[historyText setSel:length :length];
[historyText setEditable:YES];
[historyText replaceSel:string];
[historyText setEditable:NO];
if (stringVisibleMode) [historyText scrollSelToVisible];
selectEnd(inputText);
return self;
}
- sendString:(char *)string /* Send string to the slave process. */
{
if (EOF == fputs(string, processOut)) {
fprintf(stderr, "\nCannot write.\n");
[NXApp terminate:self];
}
fflush(processOut);
return self;
}
- showPasteboard:sender /* Copy pasteboard to history view. */
{
int length;
length = [historyText textLength];
if (length >= MAXHISTORYTEXT) {
[historyText setSel:0 :(MAXHISTORYTEXT>>1)-1];
[historyText setEditable:YES];
[historyText delete:self]; /* Delete first half of text. */
return [self showPasteboard:sender]; /* Try again. */
}
[historyText setSel:length :length];
[historyText setEditable:YES];
[historyText paste:self];
[historyText setEditable:NO];
selectEnd(inputText);
return self;
}
- evalPasteboard:sender /* Copy pasteboard to history view */
{ /* and send text to the slave process. */
int stringStart, stringLength;
char *textBuffer;
stringStart = [historyText textLength];
[self showPasteboard:self];
stringLength = [historyText textLength] - stringStart + 1;
textBuffer = malloc(stringLength);
[historyText getSubstring:textBuffer start:stringStart length:stringLength];
[self sendString:textBuffer];
free (textBuffer);
return self;
}
- evalSelection:sender /* Evaluate the selection in the */
{ /* history view. */
NXSelPt selStart, selEnd; int selLength;
if ([[[historyText window] firstResponder] isDescendantOf:historyText]) {
/* getSel fails unless historyText is in the responder's view chain. */
[historyText getSel:&selStart :&selEnd];
selLength = selEnd.cp - selStart.cp;
if (selLength > 0) {
[historyText copy:self];
return [self evalPasteboard:self];
}
}
NXBeep(); /* Beep on failure. */
return self;
}
- evalInput:sender /* Cut text from input view into */
{ /* the pasteboard and perform */
int length; /* evalPasteboard. */
length = [inputText textLength];
if (length > 0) {
[inputText setSel:length :length];
[inputText replaceSel:"\n"]; /* Add a return. */
[inputText selectAll:self];
[inputText cut:self];
return [self evalPasteboard:self];
}
[inputText selectAll:self];
return self;
}
- sendInterrupt:sender
{
(void) interruptSlaveProcess();
return self;
}
/* As a listener delegate. */
- (int)evalString:(char *)string /* Copies string to historyText */
{ /* and then sends string to slave. */
[self showString:string]; /* Used to respond to a remote message. */
[self sendString:string];
return 0; /* Signal success. */
}
/* As an application delegate. */
- appDidInit:sender
{
[inputText setFont:displayFont];
[[inputText window] makeKeyAndOrderFront:self];
[inputText selectAll:self];
processOut = startSlaveProcess(self);
return self;
}
- appDidBecomeActive:sender
{
[[inputText window] makeKeyAndOrderFront:self];
return self;
}
/* As a Text delegate. */
- textDidEnd:sender endChar:(unsigned short)whyEnd
{
if (whyEnd == NX_RETURN)
return [self evalInput:self];
else
return self;
}
@end